<!-- LLM Providers Tab -->
<div id="tabLLMProviders" class="tab-content">
    <div class="endpoint-section" id="llmProvidersList">
        <h2>
            <span class="endpoint-method get">GET</span>
            <span class="endpoint-path">/api/v1/llm/providers - List LLM Providers</span>
        </h2>
        <p>Get a list of all available LLM providers and models (catalog + config).
           Configured/usable providers are highlighted; others are shown for discovery.</p>

        <button class="api-button" onclick="makeRequest('llmProvidersList', 'GET', '/api/v1/llm/providers', 'none')">
            Get Providers
        </button>
        <div id="llmProvidersQueueBadge" style="display:inline-block; margin-left: 10px; font-family: monospace; font-size: 12px;"></div>
        <label style="margin-left:10px; font-family: monospace; font-size: 12px;">
            <input id="llmProvidersQueueAuto" type="checkbox" onchange="toggleQueueBadgeAuto(this.checked)"> Auto-update (30s)
        </label>

        <h3>Response:</h3>
        <pre id="llmProvidersList_response">---</pre>

        <div class="info-box" style="margin-top: 20px;">
            <h4>Provider Status Display</h4>
            <div id="llmProvidersStatus" style="margin-top: 10px;">
                <p>Click "Get Providers" to see provider status...</p>
            </div>
        </div>

        <div class="info-box" style="margin-top: 16px;">
            <h4>Severity Thresholds</h4>
            <div style="display:flex; gap:10px; align-items:center; font-family: monospace; font-size: 13px;">
                <label>LOW &lt; <input id="sevLowPct" type="number" min="0" max="100" step="0.1" style="width:80px;"> %</label>
                <label>HIGH ≥ <input id="sevHighPct" type="number" min="0" max="100" step="0.1" style="width:80px;"> %</label>
                <button class="api-button" onclick="saveSeverityThresholds()">Save</button>
            </div>
            <p style="margin-top:8px; color:#666">Values between LOW and HIGH are considered 🟠 MED.</p>
        </div>
    </div>

    <div class="endpoint-section" id="llmProviderDetail">
        <h2>
            <span class="endpoint-method get">GET</span>
            <span class="endpoint-path">/api/v1/llm/providers/{provider_name} - Get Provider Details</span>
        </h2>
        <p>Get detailed information about a specific LLM provider.</p>

        <div class="form-group">
            <label for="llmProviderDetail_name">Provider Name <span class="required">*</span>:</label>
            <select id="llmProviderDetail_name">
                <option value="">Select a provider...</option>
                <option value="openai">openai</option>
                <option value="bedrock">bedrock</option>
                <option value="anthropic">anthropic</option>
                <option value="cohere">cohere</option>
                <option value="groq">groq</option>
                <option value="qwen">qwen</option>
                <option value="openrouter">openrouter</option>
                <option value="deepseek">deepseek</option>
                <option value="mistral">mistral</option>
                <option value="google">google</option>
                <option value="huggingface">huggingface</option>
                <option value="moonshot">moonshot</option>
                <option value="zai">zai</option>
                <option value="llama.cpp">llama.cpp</option>
                <option value="kobold">kobold</option>
                <option value="ooba">ooba</option>
                <option value="tabbyapi">tabbyapi</option>
                <option value="vllm">vllm</option>
                <option value="local-llm">local-llm</option>
                <option value="ollama">ollama</option>
                <option value="aphrodite">aphrodite</option>
                <option value="custom-openai-api">custom-openai-api</option>
                <option value="custom-openai-api-2">custom-openai-api-2</option>
            </select>
        </div>

        <button class="api-button" onclick="makeRequest('llmProviderDetail', 'GET', '/api/v1/llm/providers/{name}', 'none')">
            Get Provider Details
        </button>

        <h3>Response:</h3>
        <pre id="llmProviderDetail_response">---</pre>
    </div>

    <div class="endpoint-section" id="llmModelsList">
        <h2>
            <span class="endpoint-method get">GET</span>
            <span class="endpoint-path">/api/v1/llm/models - List All Available Models</span>
        </h2>
        <p>Get a flat list of all available models across all configured providers.</p>

        <button class="api-button" onclick="makeRequest('llmModelsList', 'GET', '/api/v1/llm/models', 'none')">
            Get All Models
        </button>

        <h3>Response:</h3>
        <pre id="llmModelsList_response">---</pre>

        <div class="info-box" style="margin-top: 20px;">
            <h4>Models by Provider</h4>
            <div id="llmModelsGrouped" style="margin-top: 10px;">
                <p>Click "Get All Models" to see models grouped by provider...</p>
            </div>
        </div>
    </div>
</div>

<script>
// Process and display LLM providers status
function displayProvidersStatus(data) {
    const statusDiv = document.getElementById('llmProvidersStatus');
    if (!data || !data.providers) {
        statusDiv.innerHTML = '<p>No provider data available</p>';
        return;
    }

    let html = '<table class="status-table" style="width: 100%; border-collapse: collapse;">';
    html += '<thead><tr>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Provider</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Status</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Models</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">API Key</th>';
    html += '</tr></thead><tbody>';

    data.providers.forEach(provider => {
        const isConfigured = provider.models && provider.models.length > 0;
        const statusColor = isConfigured ? 'green' : 'gray';
        const statusText = isConfigured ? 'Configured' : 'Not Configured';
        const apiKeyStatus = provider.api_key_configured ? '✓ Set' : '✗ Not Set';

        html += '<tr>';
        html += `<td style="padding: 8px; border-bottom: 1px solid #eee;"><strong>${provider.name}</strong></td>`;
        html += `<td style="padding: 8px; border-bottom: 1px solid #eee;"><span style="color: ${statusColor};">● ${statusText}</span></td>`;
        html += `<td style="padding: 8px; border-bottom: 1px solid #eee;">${provider.models ? provider.models.length : 0} models</td>`;
        html += `<td style="padding: 8px; border-bottom: 1px solid #eee;">${apiKeyStatus}</td>`;
        html += '</tr>';
    });

    html += '</tbody></table>';

    if (data.default_provider) {
        html += `<p style="margin-top: 10px;"><strong>Default Provider:</strong> ${data.default_provider}</p>`;
    }

    if (data.total_configured !== undefined) {
        html += `<p><strong>Total Configured Providers:</strong> ${data.total_configured}</p>`;
    }

    statusDiv.innerHTML = html;
}

// Process and display models grouped by provider
function displayModelsGrouped(data) {
    const modelsDiv = document.getElementById('llmModelsGrouped');
    if (!data || !data.models) {
        modelsDiv.innerHTML = '<p>No models data available</p>';
        return;
    }

    // Group models by provider
    const modelsByProvider = {};
    data.models.forEach(model => {
        const parts = model.split('/');
        const provider = parts.length > 1 ? parts[0] : 'unknown';
        const modelName = parts.length > 1 ? parts.slice(1).join('/') : model;

        if (!modelsByProvider[provider]) {
            modelsByProvider[provider] = [];
        }
        modelsByProvider[provider].push(modelName);
    });

    let html = '<div style="max-height: 400px; overflow-y: auto;">';

    Object.keys(modelsByProvider).sort().forEach(provider => {
        html += `<details style="margin-bottom: 10px;">`;
        html += `<summary style="cursor: pointer; font-weight: bold; padding: 5px; background-color: #f5f5f5;">`;
        html += `${provider} (${modelsByProvider[provider].length} models)`;
        html += `</summary>`;
        html += '<ul style="margin-top: 5px; padding-left: 20px;">';

        modelsByProvider[provider].sort().forEach(model => {
            html += `<li style="margin: 2px 0;"><code>${model}</code></li>`;
        });

        html += '</ul></details>';
    });

    html += '</div>';
    html += `<p style="margin-top: 10px;"><strong>Total Models:</strong> ${data.models.length}</p>`;

    modelsDiv.innerHTML = html;
}

// Override the default makeRequest for LLM providers to add custom processing
const originalMakeRequest = window.makeRequest;
window.makeRequest = function(sectionId, method, endpoint, bodyType) {
    // Call the original function
    const result = originalMakeRequest.call(this, sectionId, method, endpoint, bodyType);

    // Add custom processing for LLM providers responses
    if (sectionId === 'llmProvidersList') {
        setTimeout(() => {
            const responseElement = document.getElementById('llmProvidersList_response');
            if (responseElement && responseElement.textContent !== '---') {
                try {
                    const data = JSON.parse(responseElement.textContent);
                    if (typeof displayProvidersStatusEnhanced === 'function') {
                        displayProvidersStatusEnhanced(data);
                    } else {
                        displayProvidersStatus(data);
                    }
                    // Fetch queue badge
                    loadQueueBadge();
                } catch (e) {
                    console.error('Error parsing providers response:', e);
                }
            }
        }, 100);
    } else if (sectionId === 'llmModelsList') {
        setTimeout(() => {
            const responseElement = document.getElementById('llmModelsList_response');
            if (responseElement && responseElement.textContent !== '---') {
                try {
                    const data = JSON.parse(responseElement.textContent);
                    displayModelsGrouped(data);
                } catch (e) {
                    console.error('Error parsing models response:', e);
                }
            }
        }, 100);
    } else if (sectionId === 'llmProviderDetail') {
        setTimeout(() => {
            const responseElement = document.getElementById('llmProviderDetail_response');
            if (responseElement && responseElement.textContent !== '---') {
                try {
                    const data = JSON.parse(responseElement.textContent);
                    if (typeof displayProviderDetailStatus === 'function') {
                        displayProviderDetailStatus(data);
                    }
                } catch (e) {
                    console.error('Error parsing provider detail response:', e);
                }
            }
        }, 100);
    }

    return result;
};

// Initialize LLM providers tab
function initializeLLMProvidersTab() {
    console.log('LLM Providers tab initialized');

    // Auto-load providers list when tab is opened
    if (document.querySelector('#tabLLMProviders.active')) {
        makeRequest('llmProvidersList', 'GET', '/api/v1/llm/providers', 'none');
    }
    // Initialize thresholds UI with saved values or defaults
    try {
        const low = parseFloat(localStorage.getItem('llm_severity_low') || '5');
        const high = parseFloat(localStorage.getItem('llm_severity_high') || '20');
        const lowEl = document.getElementById('sevLowPct');
        const highEl = document.getElementById('sevHighPct');
        if (lowEl) lowEl.value = low;
        if (highEl) highEl.value = high;
    } catch (e) { /* ignore */ }
    // restore queue badge auto pref
    const autoEl = document.getElementById('llmProvidersQueueAuto');
    if (autoEl) {
        const saved = localStorage.getItem('llm_providers_queue_auto') === '1';
        autoEl.checked = saved;
        if (saved) toggleQueueBadgeAuto(true);
    }
}

// Call initialization when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    if (document.querySelector('#tabLLMProviders')) {
        initializeLLMProvidersTab();
    }
});

// Enhanced status table with health/capabilities
function displayProvidersStatusEnhanced(data) {
    const statusDiv = document.getElementById('llmProvidersStatus');
    if (!data || !data.providers) {
        statusDiv.innerHTML = '<p>No provider data available</p>';
        return;
    }
    let html = '<table class="status-table" style="width: 100%; border-collapse: collapse;">';
    html += '<thead><tr>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Provider</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Configured</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Health</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Models</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Auth</th>';
    html += '<th style="text-align: left; padding: 8px; border-bottom: 2px solid #ddd;">Capabilities</th>';
    html += '</tr></thead><tbody>';

    // read thresholds
    const thresholds = getSeverityThresholds();
    data.providers.forEach(provider => {
        const isConfigured = provider.is_configured === true;
        const configuredColor = isConfigured ? 'green' : 'gray';
        const configuredText = isConfigured ? 'Yes' : 'No';
        const requiresKey = provider.requires_api_key === true;
        const authText = requiresKey ? (isConfigured ? '✓ Present' : '✗ Missing') : 'Not Required';
        const health = provider.health || {};
        const healthStatus = (health.status || 'unknown').toString();
        const healthColor = healthStatus.includes('healthy') ? 'green' : (healthStatus.includes('degraded') ? 'orange' : (healthStatus.includes('unhealthy') || healthStatus.includes('open') ? 'red' : 'gray'));
        const circuit = health.circuit_breaker_state ? ` <span style=\"color:#888\">(${health.circuit_breaker_state})</span>` : '';
        const caps = provider.capabilities || {};
        const capsBits = [];
        if (caps.supports_streaming !== undefined) capsBits.push(caps.supports_streaming ? 'streaming' : 'no-stream');
        if (caps.supports_tools !== undefined) capsBits.push(caps.supports_tools ? 'tools' : 'no-tools');
        if (caps.default_timeout_seconds !== undefined) capsBits.push(`timeout=${caps.default_timeout_seconds}s`);
        if (caps.max_output_tokens_default !== undefined && caps.max_output_tokens_default !== null) capsBits.push(`max_out=${caps.max_output_tokens_default}`);
        const capsText = capsBits.join(', ');

        html += '<tr>';
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\"><strong>${provider.name}</strong></td>`;
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\"><span style=\"color: ${configuredColor};\">● ${configuredText}</span></td>`;
        // Compose health tooltip
        const totalCalls = (health.success_count || 0) + (health.failure_count || 0);
        const errRate = totalCalls > 0 ? Math.round((health.failure_count || 0) * 1000 / totalCalls)/10 : 0;
        const low = thresholds.low, high = thresholds.high;
        let sevEmoji = '🟢', sevLabel = 'LOW';
        if (errRate >= high) { sevEmoji = '🔴'; sevLabel = 'HIGH'; }
        else if (errRate >= low) { sevEmoji = '🟠'; sevLabel = 'MED'; }
        const tooltip = `severity: ${sevEmoji} ${sevLabel}\n` +
                        `status: ${healthStatus}\n` +
                        (health.circuit_breaker_state ? `circuit: ${health.circuit_breaker_state}\n` : '') +
                        `success: ${health.success_count || 0}, failure: ${health.failure_count || 0}\n` +
                        `error_rate: ${errRate}%\n` +
                        (health.average_response_time != null ? `avg_rt: ${Math.round(health.average_response_time*1000)}ms` : '');
        // Click to fetch provider details
        const onClick = `makeRequest('llmProviderDetail', 'GET', '/api/v1/llm/providers/${provider.name}', 'none');`;
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\"><span class=\\"health-badge\\" title=\\"${tooltip}\\" style=\\"background-color:${healthColor}; cursor:pointer;\\" onclick=\\"${onClick}\\">${healthStatus}</span>${circuit}</td>`;
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\">${provider.models ? provider.models.length : 0} models</td>`;
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\">${authText}</td>`;
        html += `<td style=\"padding: 8px; border-bottom: 1px solid #eee;\">${capsText || '-'}</td>`;
        html += '</tr>';
    });
    html += '</tbody></table>';
    if (data.default_provider) {
        html += `<p style=\"margin-top: 10px;\"><strong>Default Provider:</strong> ${data.default_provider}</p>`;
    }
    if (data.total_configured !== undefined) {
        html += `<p><strong>Total Configured Providers:</strong> ${data.total_configured}</p>`;
    }
    // Add mini legend for severity (dynamic thresholds)
    const thr = getSeverityThresholds();
    html += '<div class="legend" style="margin-top:8px; font-family: monospace; font-size: 12px; color:#555">'
          + `<span title="error rate < ${thr.low}%">🟢 LOW</span> `
          + `<span title="${thr.low}-${thr.high - 0.1}% error rate" style="margin-left:10px;">🟠 MED</span> `
          + `<span title=">= ${thr.high}% error rate" style="margin-left:10px;">🔴 HIGH</span>`
          + '</div>';
    statusDiv.innerHTML = html;
}

function getSeverityThresholds() {
    const low = parseFloat(localStorage.getItem('llm_severity_low') || '5');
    const high = parseFloat(localStorage.getItem('llm_severity_high') || '20');
    return { low: isNaN(low) ? 5 : low, high: isNaN(high) ? 20 : high };
}

function saveSeverityThresholds() {
    const lowEl = document.getElementById('sevLowPct');
    const highEl = document.getElementById('sevHighPct');
    const low = parseFloat(lowEl && lowEl.value ? lowEl.value : '5');
    const high = parseFloat(highEl && highEl.value ? highEl.value : '20');
    if (!isNaN(low)) localStorage.setItem('llm_severity_low', String(low));
    if (!isNaN(high)) localStorage.setItem('llm_severity_high', String(high));
    // Re-render providers list if present
    try {
        const responseElement = document.getElementById('llmProvidersList_response');
        if (responseElement && responseElement.textContent !== '---') {
            const data = JSON.parse(responseElement.textContent);
            displayProvidersStatusEnhanced(data);
        }
    } catch (e) { /* ignore */ }
}

async function loadQueueBadge() {
    try {
        const badge = document.getElementById('llmProvidersQueueBadge');
        if (!badge) return;
        const res = await fetch('/api/v1/chat/queue/status', { credentials: 'same-origin' });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        if (data && data.enabled) {
            const q = data.queue_size || 0;
            const running = data.is_running ? 'running' : 'stopped';
            badge.innerHTML = `<span class="health-badge" title="Queue status: ${running}" style="background-color:#4f7cac;">Queue: ${q}</span>`;
        } else {
            badge.innerHTML = `<span class="health-badge" style="background-color:#777;">Queue: n/a</span>`;
        }
    } catch (e) {
        // ignore errors for badge
    }
}

let __llmProvidersQueueBadgeTimer = null;
function toggleQueueBadgeAuto(enabled) {
    if (enabled) {
        if (__llmProvidersQueueBadgeTimer) clearInterval(__llmProvidersQueueBadgeTimer);
        loadQueueBadge();
        __llmProvidersQueueBadgeTimer = setInterval(loadQueueBadge, 30000);
        try { localStorage.setItem('llm_providers_queue_auto', '1'); } catch (e) {}
    } else {
        if (__llmProvidersQueueBadgeTimer) clearInterval(__llmProvidersQueueBadgeTimer);
        __llmProvidersQueueBadgeTimer = null;
        try { localStorage.removeItem('llm_providers_queue_auto'); } catch (e) {}
    }
}

// Render provider detail health/capabilities
function displayProviderDetailStatus(provider) {
    const containerId = 'llmProviderDetail_status';
    let statusDiv = document.getElementById(containerId);
    if (!statusDiv) {
        const parent = document.getElementById('llmProviderDetail');
        if (parent) {
            const box = document.createElement('div');
            box.className = 'info-box';
            box.innerHTML = `<h4>Provider Health & Capabilities</h4><div id="${containerId}" style="margin-top: 10px;"></div>`;
            parent.appendChild(box);
            statusDiv = document.getElementById(containerId);
        }
    }
    if (!statusDiv) return;
    if (!provider || !provider.name) {
        statusDiv.innerHTML = '<p>No provider selected</p>';
        return;
    }
    const caps = provider.capabilities || {};
    const health = provider.health || {};
    const healthStatus = (health.status || 'unknown').toString();
    const healthColor = healthStatus.includes('healthy') ? 'green' : (healthStatus.includes('degraded') ? 'orange' : (healthStatus.includes('unhealthy') || healthStatus.includes('open') ? 'red' : 'gray'));
    const circuit = health.circuit_breaker_state ? ` (${health.circuit_breaker_state})` : '';

    let html = '';
    html += `<p><strong>Name:</strong> ${provider.display_name || provider.name}</p>`;
    html += `<p><strong>Configured:</strong> ${provider.is_configured ? 'Yes' : 'No'}</p>`;
    html += `<p><strong>Requires API Key:</strong> ${provider.requires_api_key ? 'Yes' : 'No'}</p>`;
    html += `<p><strong>Health:</strong> <span class=\"health-badge\" style=\"background-color:${healthColor}\">${healthStatus}</span>${circuit}</p>`;
    html += '<p><strong>Capabilities:</strong></p>';
    html += '<ul>';
    if (caps.supports_streaming !== undefined) html += `<li>Streaming: ${caps.supports_streaming ? 'Yes' : 'No'}</li>`;
    if (caps.supports_tools !== undefined) html += `<li>Tools: ${caps.supports_tools ? 'Yes' : 'No'}</li>`;
    if (caps.default_timeout_seconds !== undefined) html += `<li>Default Timeout: ${caps.default_timeout_seconds}s</li>`;
    if (caps.max_output_tokens_default !== undefined && caps.max_output_tokens_default !== null) html += `<li>Default Max Output Tokens: ${caps.max_output_tokens_default}</li>`;
    html += '</ul>';
    statusDiv.innerHTML = html;
}
</script>

<style>
.info-box {
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 15px;
    margin-top: 20px;
}

.info-box h4 {
    margin-top: 0;
    color: #333;
}

.status-table {
    font-family: monospace;
    font-size: 14px;
}

details summary:hover {
    background-color: #e8e8e8 !important;
}

.health-badge {
    display: inline-block;
    color: #fff;
    border-radius: 10px;
    padding: 2px 8px;
    font-size: 12px;
    text-transform: capitalize;
}
</style>
